﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Algorithm_api.calculate.GeneContrast
{
    public class Contrast
    {
        public string gene1 { get; set; }
        public string gene2 { get; set; }
        public string cGene1 { get; set; }
        public string cGene2 { get; set; }
        public int[,] course { get; set; }
        public Gene Gene { get; set; } = new Gene();

        public Contrast(string g1,string g2)
        {
            gene1 = g1;
            gene2 = g2;
            cGene1 = "";
            cGene2 = "";
            course = new int[g1.Length + 1,g2.Length + 1];
            FillCourse();
        }


        public void FillCourse()
        {
            int g1_length = gene1.Length;
            int g2_length = gene2.Length;
            char[] g1 = gene1.ToArray();
            char[] g2 = gene2.ToArray();

            for(int i = 1; i <= g1_length; i++)
            {
                course[i,0] = course[i - 1,0] + Gene.GetPartition(g1[i - 1], '_');
            }
            for (int i = 1; i <= g2_length; i++)
            {
                course[0,i] = course[0,i - 1] + Gene.GetPartition('_', g2[i - 1]);
            } // 填充分数矩阵第1行第1列

            for(int i = 1; i <= g1_length; i++) // 填充分数矩阵中空缺部分
            {
                for(int j = 1; j <= g2_length; j++)
                {
                    int case1 = course[i - 1,j] + Gene.GetPartition(g1[i - 1], '_'); //分三种情况进行对比分数
                    int case2 = course[i - 1,j - 1] + Gene.GetPartition(g1[i - 1],g2[j - 1]);
                    int case3 = course[i,j - 1] + Gene.GetPartition('_',g2[j - 1] );
                    course[i,j] = Max(case1, case2, case3); // 挑选最优分数填写
                }
            }
        }
        

        public int Max(int n1,int n2,int n3)
        {
            int max = n1 > n2 ? n1 : n2;
            return max > n3 ? max : n3;
        }

        public ContrastResult GeneContrast()
        {
            int row = gene1.Length; //初始化行列
            int col = gene2.Length;
            char[] g1 = gene1.ToArray();
            char[] g2 = gene2.ToArray();

            while(row != 0 || col != 0)//当两个字符串访问到头即结束
            {
                //判断两种情况
                if(row == 0)//gene1访问完成 此时将gene2剩余部分全部匹配空格
                {
                    for(int i = 0; i < col; i++)
                    {
                        cGene1 = "_" + cGene1;
                    }
                    cGene2 = gene2.Substring(0, col) + cGene2;
                    break; //结束循环
                }

                if(col == 0) // 同理
                {
                    for (int i = 0; i < row; i++)
                    {
                        cGene2 = "_" + cGene2;
                    }
                    cGene1 = gene1.Substring(0, row) + cGene1;
                    break;
                }

                //将当前字符串中的字符进行对比比较分数
                int case1 = course[row - 1, col] + Gene.GetPartition(g1[row - 1], '_'); //g1与 空格对比
                int case2 = course[row, col - 1] + Gene.GetPartition(g2[col - 1], '_');//g2 与空格对比
                int case3 = course[row - 1, col - 1] + Gene.GetPartition(g1[row - 1], g2[col - 1]);//g1与g2对比
                int value = course[row, col]; // 最优得分

                if(value == case1)//第一种情况最优时
                {
                    cGene1 = g1[--row] + cGene1; //将这个字符加入改变后的字符串中
                    cGene2 = "_" + cGene2; //将空格加入改变的字符串中
                }
                else if(value == case2) //同理
                {
                    cGene1 = "_" + cGene1;
                    cGene2 = g2[--col] + cGene2;
                }
                else//当g1 g2匹配时
                {
                    cGene1 = g1[--row ] + cGene1;
                    cGene2 = g2[--col] + cGene2;
                }
            }
            //填充答案对象

            ContrastResult res = new ContrastResult()
            {
                g1 = cGene1,
                g2 = cGene2,
                maxPartition = GetGenePartition(cGene1.ToArray(), cGene2.ToArray())
            };
            return res;
        }




        public int GetGenePartition(char[] g1,char[] g2)
        {
            int sum = 0;
            for(int i = 0; i < g1.Length; i++)
            {
                sum += Gene.GetPartition(g1[i], g2[i]);
            }
            return sum;
        }
    }
}
